/*  ______   ______   ______   ______   ______   __  __   _______    
 * /_____/\ /_____/\ /_____/\ /_____/\ /_____/\ /_/\/_/\ /______/\   
 * \   __\/ \   _ \ \\   _ \ \\    _\/_\   _ \ \\ \ \ \ \\   __\/__ 
 *  \ \ \  __\ \ \ \ \\ \ \ \ \\ \/___/\\ (_) \ \\ \ \ \ \\ \ /____/\
 *   \ \ \/_/\\ \ \ \ \\ \ \ \ \\  ___\/_\  ___\/ \ \ \ \ \\ \\_  _\/
 *    \ \_\ \ \\ \_\ \ \\ \/  | |\ \____/\\ \ \    \ \_\ \ \\ \_\ \ \
 *     \_____\/ \_____\/ \____/_/ \_____\/ \_\/     \_____\/ \_____\/
 *  
 * httpd.h
 * Copyright (c) 2010 CodePug
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <wininet.h>
#include <winsock2.h>
#include <Iphlpapi.h>
#include "xutility.h"

#ifndef _HTTPD_H				// If we haven't included this file
#define _HTTPD_H	

LPCWSTR getIpAddress();
void connection(SOCKET s);
void send_headers(SOCKET s, int status, char *title, char *extra, char *mime, int length, time_t date);
DWORD WINAPI ThreadFunc(void* sd_);
void createT(SOCKET s);
void wcharToChar(char *buffer, WCHAR *w);
void getDirContents(char *buffer2);

LPCWSTR getIpAddress(){
	MIB_IPADDRTABLE  *pIPAddrTable;
	DWORD            dwSize = 0;
	DWORD            dwRetVal;
	pIPAddrTable = (MIB_IPADDRTABLE*) malloc( sizeof(MIB_IPADDRTABLE) );
	LPCWSTR result = TEXT("Starting...");

	// Retrieving struct size
	if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
		free( pIPAddrTable );
		pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize );
	}

	if ( (dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 )) != NO_ERROR ) { 
		result=TEXT("GetIpAddrTable call failed.");
	}else{
		 char buffer [50];
		 in_addr me;
		 me.S_un.S_addr = pIPAddrTable->table[0].dwAddr;
		 sprintf (buffer, "CodePug WebServer Started.\nhttp://%s\n", inet_ntoa(me));
		 result = MultiCharToUniChar(buffer);
	}
	return result;
}

void getDirContents(char *buffer2){
	LPCWSTR result = TEXT("Starting...");
	WIN32_FIND_DATA ffd;

	HANDLE hFind = INVALID_HANDLE_VALUE;
	hFind = FindFirstFile(TEXT("\\*"), &ffd);

	while (FindNextFile(hFind,&ffd))
	{
		char buffer3[MAX_PATH];
		memset(buffer3,'\0',MAX_PATH);
		wcharToChar(buffer3,ffd.cFileName);
		sprintf(buffer2,"%s<li>%s</li>",buffer2,buffer3);
	} 
}

void wcharToChar(char *buffer, WCHAR *w){
	int len = wcslen(w);
	for (int i=0;i<len;i++){
		sprintf(buffer,"%s%c",buffer,w[i]);		
	}
}

void createT(SOCKET s){
    DWORD dwThreadId, dwThrdParam = 1;
    //Handle hThread =
	CreateThread(
        NULL,                        // no security attributes
        0,                           // use default stack size
        ThreadFunc,                  // thread function
        (void *)s,                // argument to thread function
        0,                           // use default creation flags
        &dwThreadId);                // returns the thread identifier
}

DWORD WINAPI ThreadFunc(void* sd_) {
	SOCKET client;
	SOCKET sd = (SOCKET)sd_;

	if (sd == INVALID_SOCKET)
		return 0;

	client = accept(sd,NULL,NULL);

	// Start another thread
	createT(sd);

	// Call connection method in defined in other src
	connection(client);
	closesocket(client);

    return 1;
}

void openPort(short myPort){
		BOOL hostError = FALSE;
		memset(&addr,0,sizeof(addr));

		addr.sin_family = AF_INET;
		addr.sin_port = htons (myPort);
		addr.sin_addr.s_addr = htonl (INADDR_ANY);
		SOCKET sd;// = INVALID_SOCKET;

		// Create Socket
		if((sd = socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
			hostError = TRUE;

		if (bind(sd, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
			hostError = TRUE;

		if (listen(sd,5) == SOCKET_ERROR)
			hostError = TRUE;

		if (hostError)
			PostQuitMessage(0);
		else
			createT(sd);
}

void connection(SOCKET s){
	char cStr[256];
	getStringHide(s,cStr);
	send_headers(s, 200, "OK", NULL, "text/html", -1, NULL);
	putString(s,"<html><title>CodePug WebServer</title><h1>CodePug WebServer</h1><ul>");
	char dStr[10000];
	getDirContents(dStr);
	putString(s,dStr);
	putString(s,"</ul><a href=\"http://www.codepug.com\">Visit www.CodePug.com</a></html>");
}

void send_headers(SOCKET s, int status, char *title, char *extra, char *mime, 
                  int length, time_t date)
{
	putString(s,"HTTP/1.0 200 OK\r\n");
	putString(s,"Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n");
	putString(s,"Server: Zune");
	putString(s,"Content-Type: text/html\r\n");
	putString(s,"Content-Length: 50000\r\n\r\n");
}

#endif